/************************************************************
 Copyright (C), 2017, Leon, All Rights Reserved.
FileName: get_if_addr.c
Description: get interface address
Author: Leon
Version: 1.0
Date: 
Function:

History:
<author>    <time>  <version>   <description>
Leon
 ************************************************************/

#include <arpa/inet.h>
#include <sys/socket.h>
#include <netdb.h>
#include <ifaddrs.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <netinet/in.h>

#define INT32 int
enum EBAND{
	BAND24G = 0,
	BAND5G = 1
};

typedef struct _wifi_diagnostic_result{
	char radio[64];
	char ssid[64];
	char bssid[64];
	char mode[64];
	char channel[8];
	char signal[8];
	char sec_mode[64];
	char enc_mode[32];
	char oper_freq_band[8];
	char supp_stds[64];
	char oper_stds[32];
	char oper_ch_bw[8];
	char beacon_period[32];
	char noise[8];
	char basic_tx_rates[256];
	char supp_tx_rates[256];
	char dtim_period[32];
	
}WIFI_DIAGNOSTIC_RESULT_T;

typedef struct _wifi_diagnostic{
	char state[32];
	int result_number;
	int cur_num;
	WIFI_DIAGNOSTIC_RESULT_T *result;
}WIFI_DIAGNOSTIC_T;

WIFI_DIAGNOSTIC_T wifidiag={"None", 0, 0, NULL};

void wifi_diagnostic_complete()
{
	
}

INT32 get_strsep_segment_by_index(char *string, char *delim, int index, char *segment) {
    char *s = strdup(string);
    char *token = NULL;
    INT32 count = 0;

    for(token = strsep(&s, delim); token != NULL; token = strsep(&s, delim)) {
	if(!strcmp(token, ""))
            continue;
		
        count++;
        if(count == index)
            sprintf(segment, "%s", token);
    }

    return count;
}

INT32 get_wifi_scan_result_number(char *cmd)
{
	FILE *fp = NULL;
	char buff[512] = {0};
	char total[32] = {0};
	int ret = 0;

	fp = popen(cmd, "r");

	if(fp == NULL)
		return 0;

	while(fgets(buff, sizeof(buff), fp)){
		ret = sscanf(buff, "Total=%[0-9]*", total);
		if(1 == ret){
			break;
		}
		else{
			continue;
		}
	}
	return atoi(total);	
}

INT32 get_wifi_scan_result(char *cmd, enum EBAND band)
{
	FILE *fp = NULL;
	char buff[512] = {0};
	char total[32] = {0};
	char no[8] = {0};
	char ch[64] = {0};
	char ssid[64] = {0};
	char bssid[64] = {0};
	char security[64] = {0};
	char signal[64] = {0};
	char mode[64] = {0};
	char extch[64] = {0};
	char nt[64] = {0};
	char wps[64] = {0};
	char dpid[64] = {0}; //no dpid value
	char bcnrept[64] = {0};
	char sec_mode[32] = {0};
	char enc_mode[32] = {0};
	int ret = 0;
	int cnt = 0;

	fp = popen(cmd, "r");

	if(fp == NULL)
		return 0;
	
	printf("----- cmd = [%s] -----\n", cmd);
	while(fgets(buff, sizeof(buff), fp)){
		ret = sscanf(buff, "%[0-9] %[0-9] %s %s %s %[0-9] %s %s %s %s %s *", 
			no, ch, ssid, bssid, security, signal, mode, extch, nt, wps, bcnrept);
		if(11 == ret){
			cnt++;
			//printf("band=[%s] cnt=%d %s %s %s %s %s %s %s %s %s %s %s\n", 
			//band==BAND24G ? "2.4G":"5G",cnt, no, ch, ssid, bssid, security, signal, mode, extch, nt, wps, bcnrept);
			strcpy(wifidiag.result[wifidiag.cur_num].radio, band==BAND24G ? "Device.WiFi.Radio.1.":"Device.WiFi.Radio.3.");
			strcpy(wifidiag.result[wifidiag.cur_num].ssid, ssid);
			strcpy(wifidiag.result[wifidiag.cur_num].bssid, bssid);
			strcpy(wifidiag.result[wifidiag.cur_num].mode, strcasestr(nt, "In") ? "Infrastructure":"AdHoc" );
			strcpy(wifidiag.result[wifidiag.cur_num].channel, ch);
			strcpy(wifidiag.result[wifidiag.cur_num].signal, signal);
			get_strsep_segment_by_index(security, "/", 1, sec_mode);
			strcpy(wifidiag.result[wifidiag.cur_num].sec_mode, sec_mode);
			get_strsep_segment_by_index(security, "/", 2, enc_mode);
			strcpy(wifidiag.result[wifidiag.cur_num].enc_mode, enc_mode);
			strcpy(wifidiag.result[wifidiag.cur_num].oper_freq_band, band==BAND24G ? "2.4G":"5G");
			strcpy(wifidiag.result[wifidiag.cur_num].supp_stds, mode);
			strcpy(wifidiag.result[wifidiag.cur_num].oper_stds, mode);
			if(band == BAND24G)
				if(strcasestr(extch, "ABOVE"))
					strcpy(wifidiag.result[wifidiag.cur_num].oper_ch_bw, "40MHz");
				else
					strcpy(wifidiag.result[wifidiag.cur_num].oper_ch_bw, "20MHz");
			else if(band == BAND5G)
				if(strcasestr(extch, "BELOW"))
					strcpy(wifidiag.result[wifidiag.cur_num].oper_ch_bw, "20MHz");
				else if(strcasestr(extch, "ABOVE"))
					strcpy(wifidiag.result[wifidiag.cur_num].oper_ch_bw, "40MHz");
			strcpy(wifidiag.result[wifidiag.cur_num].beacon_period, "");
			strcpy(wifidiag.result[wifidiag.cur_num].noise, "");
			strcpy(wifidiag.result[wifidiag.cur_num].basic_tx_rates, "");
			strcpy(wifidiag.result[wifidiag.cur_num].supp_tx_rates, "");
			strcpy(wifidiag.result[wifidiag.cur_num].dtim_period, "");
			wifidiag.cur_num++;
			//break;
		}
		else{
			continue;
		}
	}
	return atoi(total);	
}

void init_wifi_diagnostic(int number)
{
	if(wifidiag.result){
		printf("dbg---> free before\n");
		free(wifidiag.result);
		printf("dbg---> free after\n");
	}

	wifidiag.result_number = number;
	wifidiag.cur_num = 0;
	wifidiag.result = (WIFI_DIAGNOSTIC_RESULT_T *)malloc(sizeof(WIFI_DIAGNOSTIC_RESULT_T)*number);
}

void reset_wifi_diagnostic()
{
	free(wifidiag.result);
	wifidiag.result_number = 0;
	wifidiag.cur_num = 0;
}

void run_wifi_diagnostic()
{
	INT32 cnt = 0;
	INT32 number = 0;
	char cmd_a[64] = "cat ./result2.txt";
	char cmd_b[64] = "cat ./result5.txt";
	char cmd_scan_a[64] = "iwpriv ra0 set SiteSurvey=1";
	char cmd_scan_b[64] = "iwpriv rai0 set SiteSurvey=1";
	char cmd_reault_a[64] = "iwpriv ra0 get_site_survey";
	char cmd_result_b[64] = "iwpriv rai0 get_site_survey";

	//number += get_wifi_scan_result_number(cmd_scan_a);
	//number += get_wifi_scan_result_number(cmd_scan_b);
	number += get_wifi_scan_result_number(cmd_a);
	number += get_wifi_scan_result_number(cmd_b);
	init_wifi_diagnostic(number);
	//get_wifi_scan_result(cmd_result_a);
	//get_wifi_scan_result(cmd_result_b);
	get_wifi_scan_result(cmd_a, BAND24G);
	get_wifi_scan_result(cmd_b, BAND5G);
}

int main(int argc, char *argv[])
{
	int index;
    //char buf[256] = {0};

    //struct sockaddr_in6 *list = malloc(16 * sizeof(struct sockaddr_in6));
    //get_if_addr6(argv[1], list, 16);
    //cnt = get_if_addr6(argv[1], atoi(argv[2]));
	printf("dbg---> round one <-----\n");
	run_wifi_diagnostic();
	printf("result_number = [%d]\n", wifidiag.result_number);
	printf("dbg---> round two <-----\n");
	run_wifi_diagnostic();
	printf("result_number = [%d]\n", wifidiag.result_number);
#if 0
	for(index = 0; index < wifidiag.result_number; index++){
		printf("index=[%d], [%s] [%s] [%s] [%s] [%s] [%s] [%s] [%s] [%s] [%s] [%s] [%s] [%s] [%s] [%s] [%s] [%s]\n", index,
            wifidiag.result[index].radio,
            wifidiag.result[index].ssid,
            wifidiag.result[index].bssid,
            wifidiag.result[index].mode,
            wifidiag.result[index].channel,
            wifidiag.result[index].signal,
            wifidiag.result[index].sec_mode,
            wifidiag.result[index].enc_mode,
            wifidiag.result[index].oper_freq_band,
            wifidiag.result[index].supp_stds,
            wifidiag.result[index].oper_stds,
            wifidiag.result[index].oper_ch_bw,
            wifidiag.result[index].beacon_period,
            wifidiag.result[index].noise,
            wifidiag.result[index].basic_tx_rates,
            wifidiag.result[index].supp_tx_rates,
            wifidiag.result[index].dtim_period);
	}
#endif
	printf("wifidiag.state=[%s]\n", wifidiag.state);
	strcpy(wifidiag.state, "Completed");
	printf("wifidiag.state=[%s]\n", wifidiag.state);

    return 0;
}
